package com.tony.akka.sample2;

import akka.actor.*;
import akka.japi.pf.ReceiveBuilder;
import com.tony.akka.StdIn;
import scala.PartialFunction;
import scala.runtime.BoxedUnit;

/**
 * @version V1.0  </br>
 * @ClassName App </br>
 * @Description TODO  </br>
 * @Author tonywang</br>
 * @DATE 3/19/2019 10:18 AM</br>
 */
public class App {
    static class Alarm extends AbstractLoggingActor {
        static class Activity {
        }

        static class Disable {
            private final String password;

            public Disable(String password) {
                this.password = password;
            }
        }

        static class Enable {
            private final String password;

            public Enable(String password) {
                this.password = password;
            }
        }

        private final String password;
        private final Receive enabled;
        private final Receive disabled;

        public Alarm (String pPassword) {
            password = pPassword;
            enabled = ReceiveBuilder.create()
                    .match(Activity.class, this::onActivity)
                    .match(Disable.class, this::onDisable)
                    .build();
            disabled = ReceiveBuilder.create()
                    .match(Enable.class, this::onEnable)
                    .build();
        }
        @Override
        public Receive createReceive() {
            return disabled;
        }

        private void onEnable(Enable enable) {
            if (password.equals(enable.password)) {
                log().info("Alarm enable");
                getContext().become(enabled);
            } else {
                log().info("Someone failed to enable the alarm");
            }
        }

        private void onDisable(Disable disable) {
            if (password.equals(disable.password)) {
                log().info("Alarm disabled");
                getContext().become(disabled);
            } else {
                log().warning("Someone who didn't know the password tried to disable it");
            }
        }

        private void onActivity(Activity ignored) {
            log().warning("oeoeoeoeoe, alarm alarm!!!");
        }

        public static Props props(String pPassword){
            return Props.create(Alarm.class, pPassword);
        }
    }

    public static void main(String[] args){
        ActorSystem system = ActorSystem.create("sample2");
        ActorRef alarmActor = system.actorOf(Alarm.props("cat"), "AlarmActor");

        alarmActor.tell(new Alarm.Activity(), ActorRef.noSender());
        alarmActor.tell(new Alarm.Enable("cat"), ActorRef.noSender());
        alarmActor.tell(new Alarm.Disable("cat"), ActorRef.noSender());
        alarmActor.tell(new Alarm.Enable("dog"), ActorRef.noSender());
        //上面状态未改变成功 下面不会被执行
        alarmActor.tell(new Alarm.Activity(), ActorRef.noSender());
        alarmActor.tell(new Alarm.Disable("dog"), ActorRef.noSender());

        System.out.println("ENTER to terminate");
        StdIn.readLine();
        system.terminate();
    }
}
